package com.kingyun.gpsinspection.purificationservice.services.jsm.outerservice.impl;

import com.kingyun.gpsinspection.purificationservice.dao.mapper.jsm.DepartmentMapper;
import com.kingyun.gpsinspection.purificationservice.facade.model.jsm.*;
import com.kingyun.gpsinspection.purificationservice.facade.service.jsm.OutOrganizationService;
import com.kingyun.gpsinspection.purificationservice.facade.service.jsm.OutZtreeService;
import com.kingyun.gpsinspection.purificationservice.facade.service.jsm.department.JsmDepartmentService;
import com.kingyun.gpsinspection.purificationservice.facade.service.jsm.employee.JsmEmployeeService;
import com.kingyun.gpsinspection.purificationservice.facade.service.jsm.organization.JsmOrganizationService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

/**
 * @version V1.0
 * @Package com.cqhilink.iot.jobstandardmanagement.services.innerservice.impl.wwpaccount
 * @Description: ${TODO}(用一句话描述该文件做什么)
 * @author: HZ
 * @date: 2016/11/16,0016
 */

public class OutOrganizationServiceImpl implements OutOrganizationService {
    @Autowired
    private JsmOrganizationService orgService;
    @Autowired
    private JsmEmployeeService employeeService;
    @Autowired
    private JsmOrganizationService organizationService;
    @Autowired
    private JsmDepartmentService departmentService;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private OutZtreeService outZtreeService;

    /**
     * 查询组织机构树
     *
     * @param organization 按Id查询
     * @return
     * @throws Exception
     */
    @Override
    public List<Ztree> queryOrgTree(Organization  organization) throws Exception {
        return orgService.queryOrgTrees(organization);
    }

    /**
     * @param orgId 组织机构id
     * @t
     */
    @Override
    public Organization queryOrganization(String orgId) throws Exception {
        return orgService.findOrgById(orgId);
    }

    /**
     * 按上级机构ID查询下级机构列表
     * @param parentid
     * @return
     * @throws Exception
     */
    @Override
    public List<Organization> queryNodeByParentId(String parentid) throws Exception {
        return orgService.queryNodeByOrgId(parentid);
    }

    public JsmOrganizationService getOrgService() {
        return orgService;
    }

    public void setOrgService(JsmOrganizationService orgService) {
        this.orgService = orgService;
    }

    /**
     * @param employee 人员信息数据组合 ； 人员Id 必填
     * @param maxLevel  最大组织层级
     * @param lessLevel 最小组织层级
     */
    @Override
    public List<Organization> getOrganizationList(Employee employee, String maxLevel, String lessLevel) throws Exception {
        return orgService.getOrganizationList(employee,maxLevel,lessLevel);
    }



    /**
     * 加载组织和部门混合树
     * @param orgId
     * @param sync
     * @param openOrg
     * @param openDept
     * @param keyword
     * @return
     * @throws Exception
     */
    @Override
    public List<Ztree> loadOrgDeptZtree(String orgId, boolean sync, boolean openOrg, boolean openDept, String keyword) throws Exception {
        List<Ztree> ztreeList = new ArrayList<>();

        if(StringUtils.isEmpty(keyword)){
            //初始化加载组织部门树
            if (sync) {
                if (StringUtils.isNotEmpty(orgId)) {
                    //查询当前组织
                    Organization organization = organizationService.findOrgById(orgId);
                    //查询当前组织的所有儿子组织：去掉管线pipeline和井口well，这个种组织下不能挂人
                    List<Organization> orgList = organizationService.queryNodeByOrgId(orgId);
                    //当前组织和儿子组织：加入人员树
                    orgList.add(organization);
                    List<Ztree> orgZtreeList = organizationService.setZtree(orgList);
                    //重新设置isParent
                    for (Ztree orgZt : orgZtreeList) {
                        setOrgZtreeIsParent(orgZt, orgZt.getId());
                    }
                    ztreeList.addAll(orgZtreeList);


                    //查询当前组织下的部门
                    List<Ztree> depZtrelList = departmentService.getDeptZtreeByOrgId(orgId);
                    //重新设置isParent
                    if (depZtrelList != null) {
                        for (Ztree depZt : depZtrelList) {
                            //组织下的部门加入人员树
                            setDepZtreeIsParent(depZt, depZt.getId());
                            ztreeList.add(depZt);
                        }
                    }
                }
                //异步加载后代组织和部门
            } else {
                if (StringUtils.isNotEmpty(orgId)) {
                    if (openOrg) {
                        //查询当前组织的所有儿子组织
                        List<Organization> orgList = organizationService.queryNodeByOrgId(orgId);
                        List<Ztree> orgZtreeList = organizationService.setZtree(orgList);
                        //重新设置isParent
                        for (Ztree orgZt : orgZtreeList) {
                            setOrgZtreeIsParent(orgZt, orgZt.getId());
                        }
                        ztreeList.addAll(orgZtreeList);

                        //查询当前组织下的儿子部门
                        List<Ztree> depZtreelList = departmentService.getDeptZtreeByOrgId(orgId);
                        //重新设置isParent
                        if (depZtreelList != null) {
                            for (Ztree depZt : depZtreelList) {
                                //组织下的部门加入人员树
                                setDepZtreeIsParent(depZt, depZt.getId());
                                ztreeList.add(depZt);
                            }
                        }

                    }

                    if (openDept) {
                        //查询当前部门下的儿子部门
                        List<Ztree> depZtrelList = departmentService.queryDeptTreeByPDId(orgId);
                        if (depZtrelList != null) {
                            for (Ztree depZt : depZtrelList) {
                                //部门下的部门加入人员树
                                setDepZtreeIsParent(depZt, depZt.getId());
                                ztreeList.add(depZt);
                            }
                        }
                    }
                }
            }
        }else{
            //初始化加载组织部门树：同时挂人员
            if (sync) {
                List<Ztree> totalZtreeList = this.getOrgDeptMixedZtreeByOrgId(orgId);

                outZtreeService.removeDuplicate(totalZtreeList);

                if(totalZtreeList != null && totalZtreeList.size()>0){
                    //查询包含搜索字符的节点：并加入结果树
                    List<Ztree> targetNodeList = new ArrayList<>();
                    for(Ztree ztree : totalZtreeList){
                        if(ztree.getName() != null){
                            if(ztree.getName().toLowerCase().contains(keyword.toLowerCase())){
                                targetNodeList.add(ztree);
                            }
                        }
                    }
                    ztreeList.addAll(targetNodeList);

                    //查询包含搜索字符的节点的祖先节点：并加入结果树
                    for(Ztree ztree : targetNodeList){
                        List tempZtreeList = new ArrayList<>();
                        //递归查找祖先节点：不包括自身
                        outZtreeService.getAncestorNodeList(ztree, totalZtreeList, tempZtreeList);
                        ztreeList.addAll(tempZtreeList);
                    }

                    //必须去重：因为不同的目标节点可以有共通的父节点
                    outZtreeService.removeDuplicate(ztreeList);
                }
            //异步加载后代组织和部门及其下面挂的人员
            }else{
                if (!StringUtils.isEmpty(orgId)) {
                    if (openOrg) {
                        //查询当前组织的所有儿子组织
                        List<Organization> orgList = organizationService.queryNodeByOrgId(orgId);
                        List<Ztree> orgZtreeList = organizationService.setZtree(orgList);
                        //重新设置isParent
                        for (Ztree orgZt : orgZtreeList) {
                            setOrgZtreeIsParent(orgZt, orgZt.getId());
                        }
                        ztreeList.addAll(orgZtreeList);

                        //查询当前组织下的儿子部门
                        List<Ztree> depZtreelList = departmentService.getDeptZtreeByOrgId(orgId);
                        if (depZtreelList != null) {
                            for (Ztree depZt : depZtreelList) {
                                //组织下的部门加入人员树
                                setDepZtreeIsParent(depZt, depZt.getId());
                                ztreeList.add(depZt);
                            }
                        }
                    }

                    if (openDept) {
                        //查询当前部门下的儿子部门
                        List<Ztree> depZtrelList = departmentService.queryDeptTreeByPDId(orgId);
                        if (depZtrelList != null) {
                            for (Ztree depZt : depZtrelList) {
                                //部门下的部门加入人员树
                                setDepZtreeIsParent(depZt, depZt.getId());
                                ztreeList.add(depZt);
                            }
                        }
                    }
                }
            }
        }

        return ztreeList;
    }

    /**
     * 获取指定组织下的所有后代组织、后代部门、后代人员的混合树
     * @param orgId
     * @return
     */
    public List<Ztree> getOrgDeptMixedZtreeByOrgId(String orgId) throws Exception{
        List<Ztree> ztreeList = new ArrayList<>();
        if(StringUtils.isNotEmpty(orgId)){
            //树查询自身及后代节点：向下遍历
            List<Organization> orgList = organizationService.selectDownByTree(orgId);
            List<Ztree> orgZtreeList = organizationService.setZtree(orgList);
            //重新设置isParent
            for (Ztree orgZt : orgZtreeList) {
                setOrgZtreeIsParent(orgZt, orgZt.getId());
            }
            ztreeList.addAll(orgZtreeList);

            for(Organization org : orgList){
                //所有组织下的后代部门加入人员树
                List<Ztree> depZtreelList = departmentService.getDeptZtreeByOrgId(org.getOrgId());
                if (depZtreelList != null) {
                    for (Ztree depZt : depZtreelList) {
                        //组织下的部门加入人员树
                        setDepZtreeIsParent(depZt, depZt.getId());
                        ztreeList.add(depZt);
                    }
                }
            }

            return ztreeList;
        }else{
            return  null;
        }
    }

    /**
     * 组织和部门的混合树的设置组织的ztree的isParent
     * @param ztree
     * @param orgId
     * @throws Exception
     */
    public void setOrgZtreeIsParent(Ztree ztree, String orgId) throws Exception{
        //查询当前组织的所有儿子组织
        List<Organization> orgList = organizationService.queryNodeByOrgId(orgId);
        //查询当前组织下的部门
        List<Ztree> depZtreelList = departmentService.getDeptZtreeByOrgId(orgId);
        if((orgList != null && orgList.size()>0) || (depZtreelList!=null && depZtreelList.size()>0 )){
            ztree.setIsParent(true);
        }else{
            ztree.setIsParent(false);
        }
    }

    /**
     * 组织和部门的混合树的设置部门的ztree的isParent
     * @param ztree
     * @param depId
     * @throws Exception
     */
    @Override
    public void setDepZtreeIsParent(Ztree ztree, String depId) throws Exception {
        List<DepartmentVo> sonDepList = departmentMapper.selectByPDId(depId);

        if((sonDepList != null && sonDepList.size()>0)){
            ztree.setIsParent(true);
        }else{
            ztree.setIsParent(false);
        }
    }


    /**
     * @param employee 人员信息数据组合 ；
     */
    @Override
    public List<Organization> getOrganizationList(Employee employee) throws Exception {
        return orgService.getOrganizationList(employee);
    }

    @Override
    public List<Ztree> offsetZtree(List<Organization> organizationList) throws Exception {
        return orgService.setZtree(organizationList);
    }

    /**
     * 根据当前登录的组织id（所属组织是作业区及以下时，返回作业区；所属组织是作业区以上时返回本身）
     * @param userId
     * @return
     */
    @Override
    public String getUserOrgId(String userId) throws Exception{
        EmployeeVo employeeVo = employeeService.findEmployeeById(userId);
        Organization organization = orgService.findOrgById(employeeVo.getOrgId());
        int orgLevelId = Integer.parseInt(organization.getOrgLevelId());
        if( orgLevelId > 3 ){
            return orgService.getUserOrgId(organization.getOrgId());
        }else{
            return organization.getOrgId();
        }
    }


}
